package ch.usi.inf.pf2.gui;

import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import javax.swing.KeyStroke;
import javax.swing.border.Border;

import ch.usi.inf.pf2.gui.chart.JSpreadSheetChart;
import ch.usi.inf.pf2.gui.listener.ChangeBorderActionListener;
import ch.usi.inf.pf2.gui.listener.ChangeColorActionListener;
import ch.usi.inf.pf2.gui.listener.CloseActionListener;
import ch.usi.inf.pf2.gui.listener.CopyActionListener;
import ch.usi.inf.pf2.gui.listener.CutActionListener;
import ch.usi.inf.pf2.gui.listener.HelpActionListener;
import ch.usi.inf.pf2.gui.listener.InsertColumnListener;
import ch.usi.inf.pf2.gui.listener.InsertRowListener;
import ch.usi.inf.pf2.gui.listener.NewActionListener;
import ch.usi.inf.pf2.gui.listener.OpenActionListener;
import ch.usi.inf.pf2.gui.listener.PasteActionListener;
import ch.usi.inf.pf2.gui.listener.RedoActionListener;
import ch.usi.inf.pf2.gui.listener.SaveActionListener;
import ch.usi.inf.pf2.gui.listener.SaveAsActionListener;
import ch.usi.inf.pf2.gui.listener.UndoActionListener;

/**
 * Create the menu for the spreadsheet
 * 
 * @author Lorenzo Baracchi, Ebrisa Savina Mastrodicasa
 * 
 */
public class JSpreadSheetMenu {
	final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
	private JSpreadSheetGUI spreadTable;
	private JMenuBar menuBar;
	private JMenu fileMenu;
	private JMenu edit;
	private JMenu insert;
	private JMenu help;

	/**
	 * Create the menu
	 * 
	 * @param frame
	 *            the frame where to put the menu
	 */
	public JSpreadSheetMenu(JSpreadSheetGUI spreadTable) {
		this.spreadTable = spreadTable;
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		edit = new JMenu("Edit");
		insert = new JMenu("Insert");
		help = new JMenu("Help");
	}

	/**
	 * Creates the sub-menus
	 */
	public void makeMenus() {
		makeFileMenu();
		makeEditMenu();
		makeInsertMenu();
		makeHelpMenu();
	}

	/**
	 * Create the File menu
	 */
	public void makeFileMenu() {
		menuBar.add(fileMenu);

		// File Menu: NEW
		JMenuItem newItem = new JMenuItem("New");
		newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
				SHORTCUT_MASK));
		newItem.addActionListener(new NewActionListener(spreadTable));
		fileMenu.add(newItem);

		// File Menu: OPEN
		JMenuItem openItem = new JMenuItem("Open");
		openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
				SHORTCUT_MASK));
		openItem.addActionListener(new OpenActionListener(spreadTable));
		fileMenu.add(openItem);

		fileMenu.addSeparator();

		// File Menu: SAVE
		final JMenuItem saveItem = new JMenuItem("Save");
		saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
				SHORTCUT_MASK));
		saveItem.setEnabled(false);
		saveItem.addActionListener(new SaveActionListener(spreadTable));
		fileMenu.add(saveItem);

		// File Menu: SAVE AS
		JMenuItem saveAsItem = new JMenuItem("Save as");
		saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
				SHORTCUT_MASK));
		saveAsItem.addActionListener(new SaveAsActionListener(spreadTable,
				saveItem));
		fileMenu.add(saveAsItem);

		fileMenu.addSeparator();

		// File Menu: CLOSE
		JMenuItem closeItem = new JMenuItem("Close");
		closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W,
				SHORTCUT_MASK));
		closeItem.addActionListener(new CloseActionListener(spreadTable));
		fileMenu.add(closeItem);
	}

	
	/**
	 * Create the edit menu
	 */
	public void makeEditMenu() {
		menuBar.add(edit);

		// Edit Menu: UNDO
		JMenuItem undoItem = new JMenuItem("Undo");
		undoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z,
				SHORTCUT_MASK));
		undoItem.addActionListener(new UndoActionListener(spreadTable));
		edit.add(undoItem);

		// Edit Menu: REDO
		JMenuItem redoItem = new JMenuItem("Redo");
		redoItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
				SHORTCUT_MASK));
		redoItem.addActionListener(new RedoActionListener(spreadTable));
		edit.add(redoItem);

		edit.addSeparator();

		// Edit Menu: CUT
		JMenuItem cutItem = new JMenuItem("Cut");
		cutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
				SHORTCUT_MASK));
		cutItem.addActionListener(new CutActionListener(spreadTable));
		edit.add(cutItem);

		// Edit Menu: COPY
		JMenuItem copyItem = new JMenuItem("Copy");
		copyItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
				SHORTCUT_MASK));
		copyItem.addActionListener(new CopyActionListener(spreadTable));
		edit.add(copyItem);

		// Edit Menu: PASTE
		JMenuItem pasteItem = new JMenuItem("Paste");
		pasteItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,
				SHORTCUT_MASK));
		pasteItem.addActionListener(new PasteActionListener(spreadTable));
		edit.add(pasteItem);
		
		
		edit.addSeparator();
		
		
		// Edit Menu - Cell Color Menu
		JMenu cellColor = new JMenu("Manage cell color");
		edit.add(cellColor);
		
		// Cell Color Menu: GREEN
		JMenuItem greenItem = new JMenuItem("Green");
		greenItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.GREEN));		
		cellColor.add(greenItem);
		
		
		// Cell Color Menu: BLUE
		JMenuItem blueItem = new JMenuItem("Blue");
		blueItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.CYAN));
		cellColor.add(blueItem);
		
		// Cell Color Menu: PINK
		JMenuItem pinkItem = new JMenuItem("Pink");
		pinkItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.PINK));
		cellColor.add(pinkItem);
		
		// Cell Color Menu: GRAY
		JMenuItem grayItem = new JMenuItem("Gray");
		grayItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.LIGHT_GRAY));
		cellColor.add(grayItem);
		
		// Cell Color Menu: ORANGE
		JMenuItem orangeItem = new JMenuItem("Orange");
		orangeItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.ORANGE));
		cellColor.add(orangeItem);
		
		
		cellColor.addSeparator();
		
		
		// Cell Color Menu: WHITE (Default)
		JMenuItem whiteItem = new JMenuItem("Default");
		whiteItem.addActionListener(new ChangeColorActionListener(spreadTable, Color.WHITE));
		cellColor.add(whiteItem);	
		
		
		
		
		
		// Edit Menu - Cell Border Type Menu
		JMenu borderType = new JMenu("Manage border type");
		edit.add(borderType);
		
		// Cell Border Color Menu: RAISED ETCHED
		JMenuItem lineItem = new JMenuItem("Line Border");
		lineItem.addActionListener(new ChangeBorderActionListener(spreadTable, BorderFactory.createLineBorder(Color.BLACK)));
		borderType.add(lineItem);
		
		
		// Cell Border Color Menu: LOWERED BEVEL
		JMenuItem loweredBevelItem = new JMenuItem("Mark Border");
		loweredBevelItem.addActionListener(new ChangeBorderActionListener(spreadTable, BorderFactory.createLoweredBevelBorder()));
		borderType.add(loweredBevelItem);
		
		
		// Cell Border Color Menu: RAISED BEVEL
		JMenuItem raisedBevelItem = new JMenuItem("Raise Border");
		raisedBevelItem.addActionListener(new ChangeBorderActionListener(spreadTable, BorderFactory.createRaisedBevelBorder()));
		borderType.add(raisedBevelItem);
		
		
		borderType.addSeparator();
		
		
		// Cell Border Color Menu: 
		JMenuItem defaultItem = new JMenuItem("Default Border");
		defaultItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				setCellBorderType(BorderFactory.createMatteBorder(2,5,2,5,
						Color.WHITE));
				SpreadSheetTableModel tb = (SpreadSheetTableModel) spreadTable
						.getTable().getModel();
				tb.fireTableCellUpdated(spreadTable.getSelectedRow() + 1,
						spreadTable.getSelectedColumn() + 1);
				spreadTable.getSheet().setHasBeenSaved(false);
				System.out.println("DEFAULT");
			}
		});
		borderType.add(defaultItem);
	}
	
	
	
	
	
	
	/**
	 * Set the color of the cell to the desired one.
	 * @param color The desired color for the cell.
	 */
	public void setCellColor(Color color)
	{
		int r = spreadTable.getTable().getSelectedRow();
		int c = spreadTable.getTable().getSelectedColumn();
		spreadTable.getSheet().getCell(c+1, r+1).setColor(color);
	}
	
	
	/**
	 * Set the border type of the cell to the desired one.
	 * @param borderType The desired border type for the cell.
	 */
	public void setCellBorderType(Border borderType)
	{
		int r = spreadTable.getTable().getSelectedRow();
		int c = spreadTable.getTable().getSelectedColumn();
		spreadTable.getSheet().getCell(c+1, r+1).setBorderType(borderType);
	}

	
	
	/**
	 * Create the Insert menu
	 */
	public void makeInsertMenu()
	{
		menuBar.add(insert);
		// Insert Menu: FUNCTION
		JMenuItem function = new JMenuItem("Function");
		function.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				new SpreadSheetFormulaWindow(spreadTable);
			}
		});
		insert.add(function);	
		
		// Insert Menu: CONSTANTS
		JMenuItem constant = new JMenuItem("Constant");
		constant.addActionListener(new ActionListener()
		{
        	       @Override
        	       public void actionPerformed(ActionEvent arg0)
        	       {
        	     	 new InsertConstantWindow(spreadTable);
        	       }
		});
		insert.add(constant);
		
		// Insert Menu: Cell range
		JMenuItem cellRange = new JMenuItem("Cell Range");
		cellRange.addActionListener(new ActionListener()
		{
        	       @Override
        	       public void actionPerformed(ActionEvent arg0)
        	       {
        	     	 new CellRangeWindow(spreadTable);
        	       }
		});
		insert.add(cellRange);
		
		// Insert Menu: Chart
		JMenuItem chart = new JMenuItem("Chart");
		chart.addActionListener(new ActionListener()
		{
        	       @Override
        	       public void actionPerformed(ActionEvent arg0)
        	       {
        	     	JSpreadSheetChart jssc = new JSpreadSheetChart(spreadTable);
        	     	System.out.println("chart menu");
        	       }
		});
		insert.add(chart);
		
		insert.add(new JSeparator());
		
	   // Insert Menu: insert row
	   JMenuItem insRow = new JMenuItem("Insert Row");
	   insRow.addActionListener(new InsertRowListener(spreadTable));
	   insert.add(insRow);
	   
	   // Insert Menu: insert column
	   JMenuItem insCol = new JMenuItem("Insert Column");
	   insCol.addActionListener(new InsertColumnListener(spreadTable));
	   insert.add(insCol);
	}
	
	
	
	/**
	 * Create the Help menu
	 */
	public void makeHelpMenu() {
		help = new JMenu("Help");
		JMenuItem about = new JMenuItem("About");
		about.addActionListener(new HelpActionListener(spreadTable));
		help.add(about);
		menuBar.add(help);
	}

	/**
	 * Set the menu bar.
	 * 
	 * @param menubar
	 *            The bar wanted to be set.
	 */
	public void setMenubar(JMenuBar menubar) {
		this.menuBar = menubar;
	}

	/**
	 * @return The actual menubar.
	 */
	public JMenuBar getMenubar() {
		return menuBar;
	}

	/**
	 * Set the File menu.
	 * 
	 * @param fileMenu
	 *            The File menu wanted to be set.
	 */
	public void setFileMenu(JMenu fileMenu) {
		this.fileMenu = fileMenu;
	}

	/**
	 * @return The actual File menu.
	 */
	public JMenu getFileMenu() {
		return fileMenu;
	}

	/**
	 * Set the Edit menu.
	 * 
	 * @param edit
	 *            The Edit menu wanted to be set.
	 */
	public void setEditMenu(JMenu edit) {
		this.edit = edit;
	}

	/**
	 * @return The actual Edit menu.
	 */
	public JMenu getEditMenu() {
		return edit;
	}

	/**
	 * Set the Help menu.
	 * 
	 * @param help
	 *            The Help menu wanted to be set.
	 */
	public void setHelpMenu(JMenu help) {
		this.help = help;
	}

	/**
	 * @return the actual Help menu.n
	 */
	public JMenu getHelpMenu() {
		return help;
	}
}
